package com.xidian.zhiancloud.service.ledgerManager.targerAndSystem;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xidian.zhiancloud.dao.SecurityInputLedgerDetailMapper;
import com.xidian.zhiancloud.dao.SecurityInputLedgerMapper;
import com.xidian.zhiancloud.dao.syset.SysUserMapper;
import com.xidian.zhiancloud.dao.syset.usermanage.OrganizationMapper;
import com.xidian.zhiancloud.dto.xidianzyf.targetAndSystem.SecurityInputLedgerDTO;
import com.xidian.zhiancloud.enums.GeneralResponseEnums;
import com.xidian.zhiancloud.exception.CustomizeException;
import com.xidian.zhiancloud.model.SecurityInputLedger;
import com.xidian.zhiancloud.model.SecurityInputLedgerDetail;
import com.xidian.zhiancloud.model.syset.Organization;
import com.xidian.zhiancloud.model.syset.SysUser;
import com.xidian.zhiancloud.qo.ledgerManagerment.targetAndSystem.SecurityInputLedgerQO;
import com.xidian.zhiancloud.vo.ledgerManagerment.targetAndSystem.SecurityInputLedgerDTOVO;
import com.xidian.zhiancloud.vo.ledgerManagerment.targetAndSystem.SecurityInputLedgerVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: Summerless
 * @Date: 2020/11/8 23:12
 */
@Service
public class SecurityInputLedgerService extends ServiceImpl<SecurityInputLedgerMapper, SecurityInputLedger> implements IService<SecurityInputLedger> {
    @Autowired
    private SecurityInputLedgerMapper securityInputLedgerMapper;
    @Autowired
    private SecurityInputLedgerDetailMapper securityInputLedgerDetailMapper;
    @Autowired
    private OrganizationMapper organizationMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public Boolean add(SecurityInputLedgerDTO securityInputLedgerDTO) {
        updateSeasonCount(securityInputLedgerDTO);
        int result = securityInputLedgerMapper.insert(securityInputLedgerDTO.getSecurityInputLedger());
        if (result == 0) {
            throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
        }

        if (securityInputLedgerDTO.getSecurityInputLedgerDetails() != null) {
            int count = 0;
            for (int i = 0; i < securityInputLedgerDTO.getSecurityInputLedgerDetails().size(); i++) {
                securityInputLedgerDTO.getSecurityInputLedgerDetails().get(i).setSecurityInputLedgerId(securityInputLedgerDTO.getSecurityInputLedger().getId());
                securityInputLedgerDetailMapper.insert(securityInputLedgerDTO.getSecurityInputLedgerDetails().get(i));
                count++;
            }
            if (count != securityInputLedgerDTO.getSecurityInputLedgerDetails().size()) {
                throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
            }
        }
        return true;
    }

    public SecurityInputLedgerDTOVO getById(Long id) {
        SecurityInputLedger securityInputLedger = securityInputLedgerMapper.selectById(id);
        if (securityInputLedger == null) {
            throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
        }
        LambdaQueryWrapper<SecurityInputLedgerDetail> query = Wrappers.<SecurityInputLedgerDetail>lambdaQuery();
        query.eq(SecurityInputLedgerDetail::getSecurityInputLedgerId, id);
        List<SecurityInputLedgerDetail> securityInputLedgerDetails = securityInputLedgerDetailMapper.selectList(query);
        SecurityInputLedgerDTOVO res = new SecurityInputLedgerDTOVO();
        SecurityInputLedgerVO vo = new SecurityInputLedgerVO();
        BeanUtils.copyProperties(securityInputLedger, vo);

        SysUser creator = sysUserMapper.selectById(vo.getCreatorId());
        vo.setCreatorName(creator == null ? "该用户不存在" : creator.getName());

        SysUser principal = sysUserMapper.selectById(vo.getPrincipalId());
        vo.setPrincipalName(principal == null ? "该用户不存在" : principal.getName());
        SysUser approve = sysUserMapper.selectById(vo.getApproveId());
        vo.setApproveName(approve == null ? "该用户不存在" : approve.getName());
        String ids_s = vo.getUseOrganizationIds();
        long[] ids_l = Arrays.stream(ids_s.split(",")).mapToLong(Long::parseLong).toArray();

        List<String> names = Arrays.stream(ids_l).mapToObj(tmp_id -> {
            Organization org = organizationMapper.selectById(tmp_id);
            return org == null ? "该部门已被删除" : org.getName();
        }).collect(Collectors.toList());

        vo.setUseOrganizationNames(names);
        res.setSecurityInputLedgerVO(vo);
        res.setDetails(securityInputLedgerDetails);
        return res;
    }

    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public Boolean deleteByIds(Long[] ids) {
        int res = 0;
        int res2 = 0;
        for (Long id : ids) {
            QueryWrapper<SecurityInputLedgerDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("security_input_ledger_id", id);
            res += securityInputLedgerDetailMapper.delete(queryWrapper);
            res2 += securityInputLedgerMapper.deleteById(id);
        }
        if (res == 0 || res2 == 0) {
            return false;
        }
        return true;
    }

    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public Boolean patchById(SecurityInputLedgerDTO securityInputLedgerDTO) {
        updateSeasonCount(securityInputLedgerDTO);
        SecurityInputLedger securityInputLedger = securityInputLedgerDTO.getSecurityInputLedger();
        List<SecurityInputLedgerDetail> list = securityInputLedgerDTO.getSecurityInputLedgerDetails();
        int result = securityInputLedgerMapper.updateById(securityInputLedger);
        if (result == 0) {
            throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
        }
        LambdaQueryWrapper<SecurityInputLedgerDetail> query = Wrappers.<SecurityInputLedgerDetail>lambdaQuery();
        query.eq(SecurityInputLedgerDetail::getSecurityInputLedgerId, securityInputLedger.getId());
        securityInputLedgerDetailMapper.delete(query);
        list.forEach(detail -> {
            detail.setSecurityInputLedgerId(securityInputLedger.getId());
            securityInputLedgerDetailMapper.insert(detail);
        });
        return true;
    }

    public IPage<SecurityInputLedgerVO> selectByQO(SecurityInputLedgerQO securityInputLedgerQO) {
        Page<SecurityInputLedgerVO> page = new Page<>(securityInputLedgerQO.getCurrent(), securityInputLedgerQO.getSize());
        OrderItem orderItem = new OrderItem();
        orderItem.setColumn("create_time").setAsc(false);
        page.getOrders().add(orderItem);
        IPage<SecurityInputLedgerVO> res = securityInputLedgerMapper.selectByQO(page, securityInputLedgerQO);
        res.getRecords().forEach(
                vo -> {
                    String[] ids = vo.getUseOrganizationIds().split(",");
                    vo.setUseOrganizationNames(Arrays.stream(ids).map(tmp_id -> {
                        Organization org = organizationMapper.selectById(tmp_id);
                        return org == null ? "该部门已被删除" : org.getName();
                    }).collect(Collectors.toList()));
                }
        );
        return res;
    }

    private void updateSeasonCount(SecurityInputLedgerDTO securityInputLedgerDTO) {
        securityInputLedgerDTO.getSecurityInputLedger().setS1(BigDecimal.valueOf(0));
        securityInputLedgerDTO.getSecurityInputLedger().setS2(BigDecimal.valueOf(0));
        securityInputLedgerDTO.getSecurityInputLedger().setS3(BigDecimal.valueOf(0));
        securityInputLedgerDTO.getSecurityInputLedger().setS4(BigDecimal.valueOf(0));
        if (securityInputLedgerDTO.getSecurityInputLedgerDetails() == null) {
            return;
        }
        for (SecurityInputLedgerDetail securityInputLedgerDetail : securityInputLedgerDTO.getSecurityInputLedgerDetails()) {
            BigDecimal s1 = new BigDecimal(0);
            s1 = s1.add(securityInputLedgerDetail.getM1() != null ? securityInputLedgerDetail.getM1() : BigDecimal.valueOf(0));
            s1 = s1.add(securityInputLedgerDetail.getM2() != null ? securityInputLedgerDetail.getM2() : BigDecimal.valueOf(0));
            s1 = s1.add(securityInputLedgerDetail.getM3() != null ? securityInputLedgerDetail.getM3() : BigDecimal.valueOf(0));
            securityInputLedgerDTO.getSecurityInputLedger().setS1(securityInputLedgerDTO.getSecurityInputLedger().getS1().add(s1));

            BigDecimal s2 = new BigDecimal(0);
            s2 = s2.add(securityInputLedgerDetail.getM4() != null ? securityInputLedgerDetail.getM4() : BigDecimal.valueOf(0));
            s2 = s2.add(securityInputLedgerDetail.getM5() != null ? securityInputLedgerDetail.getM5() : BigDecimal.valueOf(0));
            s2 = s2.add(securityInputLedgerDetail.getM6() != null ? securityInputLedgerDetail.getM6() : BigDecimal.valueOf(0));
            securityInputLedgerDTO.getSecurityInputLedger().setS2(securityInputLedgerDTO.getSecurityInputLedger().getS2().add(s2));

            BigDecimal s3 = new BigDecimal(0);
            s3 = s3.add(securityInputLedgerDetail.getM7() != null ? securityInputLedgerDetail.getM7() : BigDecimal.valueOf(0));
            s3 = s3.add(securityInputLedgerDetail.getM8() != null ? securityInputLedgerDetail.getM8() : BigDecimal.valueOf(0));
            s3 = s3.add(securityInputLedgerDetail.getM9() != null ? securityInputLedgerDetail.getM9() : BigDecimal.valueOf(0));
            securityInputLedgerDTO.getSecurityInputLedger().setS3(securityInputLedgerDTO.getSecurityInputLedger().getS3().add(s3));

            BigDecimal s4 = new BigDecimal(0);
            s4 = s4.add(securityInputLedgerDetail.getM10() != null ? securityInputLedgerDetail.getM10() : BigDecimal.valueOf(0));
            s4 = s4.add(securityInputLedgerDetail.getM11() != null ? securityInputLedgerDetail.getM11() : BigDecimal.valueOf(0));
            s4 = s4.add(securityInputLedgerDetail.getM12() != null ? securityInputLedgerDetail.getM12() : BigDecimal.valueOf(0));
            securityInputLedgerDTO.getSecurityInputLedger().setS4(securityInputLedgerDTO.getSecurityInputLedger().getS4().add(s4));
        }
    }
}
